<script setup>
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
import { Howl } from 'howler'
import { IMG, IMG_DISABLED, BGM } from './constant.ts'

const prop = defineProps({
  active: {
    type: Boolean,
    default: false,
  },
  img: {
    type: [Object, String],
    default: () => IMG,
  },
  imgDisabled: {
    type: [Object, String],
    default: () => IMG_DISABLED,
  },
  bgm: {
    type: [String, Array],
    default: () => BGM,
  },
  autoStop: {
    type: Boolean,
    default: false,
  },
  volume: {
    type: Number,
    default: 0.35,
  },
})
const emit = defineEmits(['update:active'])
const isPlay = ref(true)
let sound = null

function toggle() {
  emit('update:active', !prop.active)
  nextTick(changeAudioState)
}

function changeAudioState() {
  if (!sound) return

  if (prop.active) {
    sound.play()
    isPlay.value = true
  } else {
    sound.pause()
    isPlay.value = false
  }
}

function windowBlue() {
  if (prop.active && isPlay.value && sound) {
    sound.pause()
  }
}

function windowFocus() {
  if (prop.active && isPlay.value && sound) {
    sound.play()
  }
}

function initSound() {
  // 销毁之前的音频实例
  if (sound) {
    sound.unload()
  }

  sound = new Howl({
    src: Array.isArray(prop.bgm) ? prop.bgm : [prop.bgm],
    autoplay: false,
    loop: true,
    volume: prop.volume,
  })

  if (prop.active && isPlay.value) {
    sound.play()
  }
}

onMounted(() => {
  initSound()

  if (prop.autoStop) {
    window.addEventListener('blur', windowBlue)
    window.addEventListener('focus', windowFocus)
  }
})

onUnmounted(() => {
  if (sound) {
    sound.stop()
    sound.unload()
  }
  isPlay.value = false
  if (prop.autoStop) {
    window.removeEventListener('blur', windowBlue)
    window.removeEventListener('focus', windowFocus)
  }
})

watch(() => prop.active, () => {
  nextTick(changeAudioState)
})

watch(() => prop.volume, (newVolume) => {
  if (sound) {
    sound.volume(newVolume)
  }
})

watch(() => prop.bgm, (newBgm) => {
  const wasPlaying = prop.active && isPlay.value
  initSound()
  if (wasPlaying) {
    sound.play()
  }
}, {deep: true})
</script>

<template>
  <img
    :src="active ? img : imgDisabled"
    alt=""
    class="m-audio-player__icon"
    @click="toggle"
  >
</template>

<style scoped>
.m-audio-player__icon {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
</style>